package com.g2.rpc.spring;

import com.g2.rpc.annotation.G2Reference;
import com.g2.rpc.config.ProtocolConfig;
import com.g2.rpc.config.RegistryConfig;
import com.g2.rpc.rpc.client.ClusterInvoker;
import com.g2.rpc.util.ProxyFactory;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.lang.reflect.Field;
import java.util.Objects;

/**
 * 描述:
 * ${DESCRIPTION}
 *
 * @author lingjiu.kong
 * @version 1.0
 * @date 2021-03-03 23:19
 */
public class PostProcessor implements ApplicationContextAware, InstantiationAwareBeanPostProcessor {

    private ApplicationContext context;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {

        // 服务暴露


        // 服务引用
        Field[] declaredFields = bean.getClass().getDeclaredFields();
        for (Field declaredField : declaredFields) {
            G2Reference annotation = declaredField.getAnnotation(G2Reference.class);
            if (Objects.nonNull(annotation)) {
                RegistryConfig registryConfig = context.getBean(RegistryConfig.class);
                ClusterInvoker clusterInvoker = new ClusterInvoker(declaredField, annotation.loadBalance(), registryConfig);
                Object proxy = ProxyFactory.getProxy(declaredField.getType(), clusterInvoker);
                declaredField.setAccessible(true);
                try {
                    declaredField.set(bean, proxy);
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    throw new RuntimeException("引用失败", e);
                }
            }
        }

        return bean;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

}
